﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace OAZCSharpSdk.OAZ
{
    public static class OAZ
    {

        private const string OAZ_DLL = "oaz.dll";
        private const string OBOT_DLL = "obot.dll ";
        /// <summary>
        /// 被好友删除
        /// </summary>
        public const int Event_Notify_Friend_Deleted = 15;
        /// <summary>
        /// 有新好友
        /// </summary>
        public const int Event_Notify_Friend_New = 19;
        /// <summary>
        /// 好友请求
        /// </summary>
        public const int Event_Notify_Friend_Reqeust = 20;
        /// <summary>
        /// 对方同意了您的好友请求
        /// </summary>
        public const int Event_Notify_Friend_Request_Accpet = 21;
        /// <summary>
        /// 对方拒绝了您的好友请求
        /// </summary>
        public const int Event_Notify_Friend_Request_Refuse = 22;


        /// <summary>
        /// 艾特QQ
        /// </summary>
        /// <param name="QQ"></param>
        /// <returns></returns>
        public static string At(long QQ)
        {
            return $"[@{QQ}] ";
        }

        /// <summary>
        /// 本地图片
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <returns></returns>
        public static string Picture(string path)
        {
            return $"[picFile,path={path}]";
        }

        /// <summary>
        /// 本地图片2
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <returns></returns>
        public static string Picture(long RobotQQ, long GroupQQ, string path)
        {
            var img = Api_UploadGroupPic(RobotQQ, GroupQQ, path);
            if (string.IsNullOrWhiteSpace(img))
            {
                throw new Exception("图片上传失败");
            }
            return img;
        }

        /// <summary>
        /// 本地图片3
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <returns></returns>
        public static string Picture2(long RobotQQ, long GroupQQ, string path)
        {
            var img = Api_UploadGroupPicEx_64(RobotQQ, GroupQQ, Convert.ToBase64String(File.ReadAllBytes(path)));
            if (string.IsNullOrWhiteSpace(img))
            {
                throw new Exception("图片上传失败");
            }
            return img;
        }

        /// <summary>
        /// 本地语音
        /// </summary>
        /// <param name="path">语音路径</param>
        /// <returns></returns>
        public static string Audio(string path)
        {
            return $"[AudioFile,path={path}]";
        }

        /// <summary>
        /// 新黄豆 例如：[newFace,name=/仔细分析,Id=314]
        /// </summary>
        /// <param name="name"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static string NewFace(string name, string id)
        {
            return $"[newFace,name={name},Id={id}]";
        }

        /// <summary>
        /// 回复消息
        /// </summary>
        /// <param name="Card"></param>
        /// <param name="Content"></param>
        /// <param name="SenderQQ"></param>
        /// <param name="RequestId"></param>
        /// <param name="SendTime"></param>
        /// <returns></returns>
        public static string Reply(string Card, string Content, string SenderQQ, string RequestId, string SendTime, string Msg)
        {
            return $"[Reply,Card={Card},Content={Content},SendQQID={SenderQQ},RequestID={RequestId},SendTime={SendTime}]{Msg}";
        }


        [DllImport(OAZ_DLL)]
        public static extern void Api_Output([MarshalAs(UnmanagedType.LPStr)] string content);

        [DllImport(OAZ_DLL)]
        public static extern void Api_SendFriendMsg(long RobotQQ, long FriendQQ, [MarshalAs(UnmanagedType.LPStr)] string MsgContent, int MsgReq = 0, long MsgRandom = 0);

        [DllImport(OAZ_DLL)]
        public static extern void Api_SendFriendXMLMsg(long RobotQQ, long FriendQQ, [MarshalAs(UnmanagedType.LPStr)] string MsgContent, int MsgReq = 0, long MsgRandom = 0);

        [DllImport(OAZ_DLL)]
        public static extern int Api_SendGroupMsg(long RobotQQ, long GroupQQ, [MarshalAs(UnmanagedType.LPStr)] string MsgContent, bool Anonymous);

        [DllImport(OAZ_DLL)]
        public static extern int Api_SendGroupXMLMsg(long RobotQQ, long GroupQQ, [MarshalAs(UnmanagedType.LPStr)] string MsgContent, bool Anonymous);

        [DllImport(OAZ_DLL)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string Api_GetManager(long RobotQQ, long GroupQQ);

        /// <summary>
        /// 获取其他人在某个群里是否被禁言，0=没有被禁言，否则为剩余禁言秒数
        /// </summary>
        /// <param name="RobotQQ"></param>
        /// <param name="GroupQQ"></param>
        /// <param name="QQ"></param>
        /// <returns></returns>
        [DllImport(OAZ_DLL)]
        public static extern int Api_getOthIsShutup(long RobotQQ, long GroupQQ, long QQ);

        [DllImport(OAZ_DLL)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string Api_GetClientkey(long RobotQQ);

        [DllImport(OAZ_DLL)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string Api_GetOnlineQQ();

        [DllImport(OAZ_DLL)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string Api_UploadGroupPic(long RobotQQ, long GroupQQ, [MarshalAs(UnmanagedType.LPStr)] string ImagePath);

        [DllImport(OAZ_DLL)]
        public static extern int Api_UpFlieGroup(long RobotQQ, long GroupQQ, [MarshalAs(UnmanagedType.LPStr)] string FilePath, [MarshalAs(UnmanagedType.LPStr)] string ToFolder);

        [DllImport(OAZ_DLL)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string Api_GetGroups(long RobotQQ);

        [DllImport(OBOT_DLL)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string Api_UploadGroupPicEx_64(long RobotQQ, long GroupQQ, [MarshalAs(UnmanagedType.LPStr)] string ImageBase64);

        public static async Task<string> GetWebCookies(long RobotQQ, string pt_aid, string aid, string ul)
        {
            var uri = new Uri(
                string.Format(
                    "https://ssl.ptlogin2.qq.com/jump?clientuin={0}&keyindex=19&style=9&pt_aid={1}&daid={2}&u1={3}&clientkey={4}&pt_report=1",
                    RobotQQ,
                    pt_aid,
                    aid,
                    HttpUtility.UrlEncode(ul),
                    Api_GetClientkey(RobotQQ)
                )
            );
            using (var handler = new HttpClientHandler())
            {
                var cookie = new System.Net.CookieContainer();
                handler.CookieContainer = cookie;
                using (var http = new HttpClient(handler))
                {
                    http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");
                    var rep = await http.GetAsync("https://ui.ptlogin2.qq.com/cgi-bin/login?pt_hide_ad=1&style=9&appid=" + pt_aid + "&pt_no_auth=1&pt_wxtest=1&daid=" + aid + "&s_url=" + HttpUtility.UrlEncode(ul));
                    rep = await http.GetAsync(uri);
                    rep.EnsureSuccessStatusCode();
                    var content = await rep.Content.ReadAsStringAsync();
                    return string.Join(";", GetAllCookies(cookie).Select(x => x.Name + "=" + x.Value));
                }
            }
        }

        private static string GetCookie(CookieContainer cook, string uri, string Name)
        {
            var cookies = cook.GetCookieHeader(new Uri(uri)).Split(';');
            return cookies.First(x =>
            {
                x = x.Replace(" ", "");
                return x.Split('=')[0] == Name;
            }).Split('=')[1];
        }

        /// <summary>
        /// 遍历CookieContainer
        /// </summary>
        /// <param name="cc"></param>
        /// <returns></returns>
        private static List<Cookie> GetAllCookies(CookieContainer cc)
        {
            List<Cookie> lstCookies = new List<Cookie>();

            Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable",
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField |
                System.Reflection.BindingFlags.Instance, null, cc, new object[] { });

            foreach (object pathList in table.Values)
            {
                SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list",
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField
                    | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { });
                foreach (CookieCollection colCookies in lstCookieCol.Values)
                    foreach (Cookie c in colCookies) lstCookies.Add(c);
            }
            return lstCookies;
        }

    }
}
